This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

source("tianfengRwrappers.R")
ds2 <- readRDS("ds2.rds")
selected_features <- read.csv("./datatable/ds2_features.csv", stringsAsFactors = F)
selected_features <- selected_features$Feature
Idents(ds2) <- ds2$seurat_clusters
ggobj <- multi_featureplot(selected_features[1:9], ds2, labels = NULL)
ggsave("ds2_features.png", device = png, height = 8, width = 8, plot = ggobj)

umap plot

ggsave("./fig2/ds2_ACumap.png", device = png, height = 4, width = 6, 
       plot = umapplot(ds2_AC, group.by = "Classification1", label.size = 5))
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the
existing scale.
ggsave("./fig2/ds2_PAumap.png", device = png, height = 4, width = 6, 
       plot = umapplot(ds2_PA, group.by = "Classification1", label.size = 5))
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the
existing scale.

Where is the Fibromyocyte

LUM

sep = 0.3
surfaceplot2("LUM",ds2,x_seq = seq(-2,13, sep), y_seq = seq(2,17,sep))

addmodulescore

geneset <- read.table("SMC")

ds2_AC <- AddModuleScore(ds2_AC,features = geneset, name = 'SMC_score')
ds2_PA <- AddModuleScore(ds2_PA,features = geneset, name = 'SMC_score')

(f("SMC_score1",label = F, ds2_AC) + scale_colour_gradient(low="#1E90FF", high="#ff2121")) %>%
  ggsave("./fig2/ds2_AC_SMCscore.png", device = png, height = 4, width = 5, plot = .)
(f("SMC_score1",label = F, ds2_PA) + scale_colour_gradient(low="#1E90FF", high="#ff2121")) %>%
  ggsave("./fig2/ds2_PA_SMCscore.png", device = png, height = 4, width = 5, plot = .)

# dataset1 <- AddModuleScore_UCell(dataset1,features = geneset, name = 'fibromyo_score')

geneset <- read.table("FB")

ds2_AC <- AddModuleScore(ds2_AC,features = geneset, name = 'FB_score')
ds2_PA <- AddModuleScore(ds2_PA,features = geneset, name = 'FB_score')

(f("FB_score1", label = F, ds2_AC) +scale_colour_gradient(low="#1E90FF", high="#ff2121")) %>%
  ggsave("./fig2/ds2_AC_FBscore.png", device = png, height = 4, width = 5, plot = .)
(f("FB_score1", label = F, ds2_PA) +scale_colour_gradient(low="#1E90FF", high="#ff2121")) %>%
  ggsave("./fig2/ds2_PA_FBscore.png", device = png, height = 4, width = 5, plot = .)

key features have gradient expression

BGN LUM

ridgetheme <- theme(plot.title = element_text(size = 15,color="black",hjust = 0.5),
                 axis.title = element_text(size = 15,color ="black"), 
                 axis.text = element_text(size = 15,color = "black"),
                 panel.grid.minor.y = element_blank(),
                 panel.grid.minor.x = element_blank(),
                 axis.text.x = element_text(angle = 0, hjust = 1),
                 panel.grid=element_blank(),
                 legend.position = "top",
                 legend.text = element_text(size= 15),
                 legend.title= element_text(size= 15)) 

ridge plot

df <- FetchData(ds2_AC,vars = c("FB_score1","SMC_score1","BGN","LUM","UMAP_1","UMAP_2"))
# df <- arrange(df,FB_score1,by_group = F)
data <- cbind(df,index = 1:nrow(df),cluster = Idents(ds2_AC))

(ggplot(data,aes(x=SMC_score1)) + geom_point(aes(y = BGN, color = cluster),alpha = 1) + geom_smooth(aes(y = BGN), color = "red") + theme_classic() + ridgetheme + scale_y_continuous(limits = c(1,5)) + scale_color_manual(values = colors_list) + theme(legend.key.size = unit(1,"cm")) + guides(colour = guide_legend(override.aes = list(size=10)))) 

(ggplot(data,aes(x=FB_score1)) + geom_point(aes(y = LUM, color = cluster),alpha = 1) + geom_smooth(aes(y = BGN), color = "green") + theme_classic() + ridgetheme +scale_y_continuous(limits = c(1,5)) + scale_color_manual(values = colors_list) + guides(colour = guide_legend(override.aes = list(size=10))))


df <- FetchData(ds2_PA,vars = c("FB_score1","SMC_score1","BGN","LUM","UMAP_1","UMAP_2"))
# df <- arrange(df,FB_score1,by_group = F)
data <- cbind(df,index = 1:nrow(df),cluster = Idents(ds2_PA))

ggplot(data,aes(x=SMC_score1)) + geom_point(aes(y = BGN, color = cluster),alpha = 1) + geom_smooth(aes(y = BGN), color = "red") + theme_classic() + ridgetheme + scale_y_continuous(limits = c(1,5)) + scale_color_manual(values = colors_list) + guides(colour = guide_legend(override.aes = list(size=10)))

ggplot(data,aes(x=FB_score1)) + geom_point(aes(y = LUM, color = cluster),alpha = 1) + geom_smooth(aes(y = BGN), color = "green") + theme_classic() + ridgetheme +scale_y_continuous(limits = c(1,5)) + scale_color_manual(values = colors_list) + guides(colour = guide_legend(override.aes = list(size=10)))

# ggplot(data,aes(x=FB_score1)) + geom_point(aes(y = BGN),color = "#e2b398",alpha = 1) + geom_smooth(aes(y = BGN), color = "red") + geom_point(aes(y=LUM),color = "#d1eba8",alpha = 1) + geom_smooth(aes(y = LUM), color = "green") + theme_classic() + ridgetheme +scale_y_continuous(limits = c(1,5))

fig.D

AC->PA

numerical umap

embedding <- FetchData(object = ds2_PA, vars = c("UMAP_1", "UMAP_2"))
embedding <- cbind(embedding, cbind(ds2_PA$X0,ds2_PA$X1,ds2_PA$X2,ds2_PA$X3))

ggobj <- ggplot() +
  geom_point(data = embedding[embedding$`1`>0.1,], 
             aes(x = UMAP_1, y = UMAP_2, color = `1`), shape=16, size = 3, alpha=0.5) + 
  scale_color_gradient('0', low = "#FFFFFF00", high = "#6dc0a6") +
  new_scale("color") +
    geom_point(data = embedding[embedding$`2`>0.1,], 
             aes(x = UMAP_1, y = UMAP_2, color = `2`),shape=16, size = 3, alpha=0.5) + 
  scale_color_gradient('1', low = "#FFFFFF00", high = "#e2b398") +
   new_scale("color") +
    geom_point(data = embedding[embedding$`3`>0.1,], 
             aes(x = UMAP_1, y = UMAP_2, color = `3`),shape=16, size = 3, alpha=0.5) + 
  scale_color_gradient('2', low = "#FFFFFF00", high = "#e2a2ca") +
  new_scale("color") +
    geom_point(data = embedding[embedding$`4`>0.1,], 
             aes(x = UMAP_1, y = UMAP_2, color = `4`),shape=16, size = 3, alpha=0.5) + 
  scale_color_gradient('3', low = "#FFFFFF00", high = "#d1eba8") +
        xlab("UMAP 1") + ylab("UMAP 2")  +
        theme(axis.line = element_line(arrow = arrow(length = unit(0.2, "cm")))) +
        scale_y_continuous(breaks = NULL) +
        scale_x_continuous(breaks = NULL) + 
  theme(panel.background = element_blank(), panel.grid = element_blank(), legend.position = "bottom")
ggsave("./fig2/sup_ds2PA_umap.png",device = png, plot = ggobj, height = 10,width = 10)

PA->AC

train on PA

numerical umap

ggsave("./fig2/sup_ds2AC_umap.png",device = png, plot = ggobj,height = 10,width = 10)
Error in FUN(X[[i]], ...) : 找不到对象'0'

GSVA

GSVAres <- readRDS("GSVAres.rds")
es <- data.frame(t(GSVAres),stringsAsFactors=F)  #可视化相关通路的在umap上聚集情况
ds2_AC <- AddMetaData(ds2_AC, es)
f("CUI_TCF21_TARGETS_UP", label = F, ds2_AC) +scale_colour_gradient(low="#1E90FF", high="#ff2121")

ds2_PA <- AddMetaData(ds2_PA, es)
f("CUI_TCF21_TARGETS_UP", label = F, ds2_PA) +scale_colour_gradient(low="#1E90FF", high="#ff2121")

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gCgpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ3RybCtTaGlmdCtFbnRlciouIAoKYGBge3J9CnNvdXJjZSgidGlhbmZlbmdSd3JhcHBlcnMuUiIpCmRzMiA8LSByZWFkUkRTKCJkczIucmRzIikKc2VsZWN0ZWRfZmVhdHVyZXMgPC0gcmVhZC5jc3YoIi4vZGF0YXRhYmxlL2RzMl9mZWF0dXJlcy5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzID0gRikKc2VsZWN0ZWRfZmVhdHVyZXMgPC0gc2VsZWN0ZWRfZmVhdHVyZXMkRmVhdHVyZQpJZGVudHMoZHMyKSA8LSBkczIkc2V1cmF0X2NsdXN0ZXJzCmdnb2JqIDwtIG11bHRpX2ZlYXR1cmVwbG90KHNlbGVjdGVkX2ZlYXR1cmVzWzE6OV0sIGRzMiwgbGFiZWxzID0gTlVMTCkKZ2dzYXZlKCJkczJfZmVhdHVyZXMucG5nIiwgZGV2aWNlID0gcG5nLCBoZWlnaHQgPSA4LCB3aWR0aCA9IDgsIHBsb3QgPSBnZ29iaikKYGBgCgojIHVtYXAgcGxvdApgYGB7cn0KZ2dzYXZlKCIuL2ZpZzIvZHMyX0FDdW1hcC5wbmciLCBkZXZpY2UgPSBwbmcsIGhlaWdodCA9IDQsIHdpZHRoID0gNiwgCiAgICAgICBwbG90ID0gdW1hcHBsb3QoZHMyX0FDLCBncm91cC5ieSA9ICJDbGFzc2lmaWNhdGlvbjEiLCBsYWJlbC5zaXplID0gNSkpCmdnc2F2ZSgiLi9maWcyL2RzMl9QQXVtYXAucG5nIiwgZGV2aWNlID0gcG5nLCBoZWlnaHQgPSA0LCB3aWR0aCA9IDYsIAogICAgICAgcGxvdCA9IHVtYXBwbG90KGRzMl9QQSwgZ3JvdXAuYnkgPSAiQ2xhc3NpZmljYXRpb24xIiwgbGFiZWwuc2l6ZSA9IDUpKQpgYGAKCiMgV2hlcmUgaXMgdGhlIEZpYnJvbXlvY3l0ZQojIyMgTFVNCmBgYHtyfQpzZXAgPSAwLjMKc3VyZmFjZXBsb3QyKCJMVU0iLGRzMix4X3NlcSA9IHNlcSgtMiwxMywgc2VwKSwgeV9zZXEgPSBzZXEoMiwxNyxzZXApKQpgYGAKCiMjICBhZGRtb2R1bGVzY29yZQpgYGB7ciBmaWcuaGVpZ2h0PTMsIGZpZy53aWR0aD0zfQpnZW5lc2V0IDwtIHJlYWQudGFibGUoIlNNQyIpCgpkczJfQUMgPC0gQWRkTW9kdWxlU2NvcmUoZHMyX0FDLGZlYXR1cmVzID0gZ2VuZXNldCwgbmFtZSA9ICdTTUNfc2NvcmUnKQpkczJfUEEgPC0gQWRkTW9kdWxlU2NvcmUoZHMyX1BBLGZlYXR1cmVzID0gZ2VuZXNldCwgbmFtZSA9ICdTTUNfc2NvcmUnKQoKKGYoIlNNQ19zY29yZTEiLGxhYmVsID0gRiwgZHMyX0FDKSArIHNjYWxlX2NvbG91cl9ncmFkaWVudChsb3c9IiMxRTkwRkYiLCBoaWdoPSIjZmYyMTIxIikpICU+JQogIGdnc2F2ZSgiLi9maWcyL2RzMl9BQ19TTUNzY29yZS5wbmciLCBkZXZpY2UgPSBwbmcsIGhlaWdodCA9IDQsIHdpZHRoID0gNSwgcGxvdCA9IC4pCihmKCJTTUNfc2NvcmUxIixsYWJlbCA9IEYsIGRzMl9QQSkgKyBzY2FsZV9jb2xvdXJfZ3JhZGllbnQobG93PSIjMUU5MEZGIiwgaGlnaD0iI2ZmMjEyMSIpKSAlPiUKICBnZ3NhdmUoIi4vZmlnMi9kczJfUEFfU01Dc2NvcmUucG5nIiwgZGV2aWNlID0gcG5nLCBoZWlnaHQgPSA0LCB3aWR0aCA9IDUsIHBsb3QgPSAuKQoKIyBkYXRhc2V0MSA8LSBBZGRNb2R1bGVTY29yZV9VQ2VsbChkYXRhc2V0MSxmZWF0dXJlcyA9IGdlbmVzZXQsIG5hbWUgPSAnZmlicm9teW9fc2NvcmUnKQoKZ2VuZXNldCA8LSByZWFkLnRhYmxlKCJGQiIpCgpkczJfQUMgPC0gQWRkTW9kdWxlU2NvcmUoZHMyX0FDLGZlYXR1cmVzID0gZ2VuZXNldCwgbmFtZSA9ICdGQl9zY29yZScpCmRzMl9QQSA8LSBBZGRNb2R1bGVTY29yZShkczJfUEEsZmVhdHVyZXMgPSBnZW5lc2V0LCBuYW1lID0gJ0ZCX3Njb3JlJykKCihmKCJGQl9zY29yZTEiLCBsYWJlbCA9IEYsIGRzMl9BQykgK3NjYWxlX2NvbG91cl9ncmFkaWVudChsb3c9IiMxRTkwRkYiLCBoaWdoPSIjZmYyMTIxIikpICU+JQogIGdnc2F2ZSgiLi9maWcyL2RzMl9BQ19GQnNjb3JlLnBuZyIsIGRldmljZSA9IHBuZywgaGVpZ2h0ID0gNCwgd2lkdGggPSA1LCBwbG90ID0gLikKKGYoIkZCX3Njb3JlMSIsIGxhYmVsID0gRiwgZHMyX1BBKSArc2NhbGVfY29sb3VyX2dyYWRpZW50KGxvdz0iIzFFOTBGRiIsIGhpZ2g9IiNmZjIxMjEiKSkgJT4lCiAgZ2dzYXZlKCIuL2ZpZzIvZHMyX1BBX0ZCc2NvcmUucG5nIiwgZGV2aWNlID0gcG5nLCBoZWlnaHQgPSA0LCB3aWR0aCA9IDUsIHBsb3QgPSAuKQpgYGAKCiMga2V5IGZlYXR1cmVzIGhhdmUgZ3JhZGllbnQgZXhwcmVzc2lvbgojIyBCR04gTFVNCmBgYHtyfQpyaWRnZXRoZW1lIDwtIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LGNvbG9yPSJibGFjayIsaGp1c3QgPSAwLjUpLAogICAgICAgICAgICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LGNvbG9yID0iYmxhY2siKSwgCiAgICAgICAgICAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSxjb2xvciA9ICJibGFjayIpLAogICAgICAgICAgICAgICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBoanVzdCA9IDEpLAogICAgICAgICAgICAgICAgIHBhbmVsLmdyaWQ9ZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLAogICAgICAgICAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9IDE1KSwKICAgICAgICAgICAgICAgICBsZWdlbmQudGl0bGU9IGVsZW1lbnRfdGV4dChzaXplPSAxNSkpIApgYGAKCiMjIHJpZGdlIHBsb3QKYGBge3J9CmRmIDwtIEZldGNoRGF0YShkczJfQUMsdmFycyA9IGMoIkZCX3Njb3JlMSIsIlNNQ19zY29yZTEiLCJCR04iLCJMVU0iLCJVTUFQXzEiLCJVTUFQXzIiKSkKIyBkZiA8LSBhcnJhbmdlKGRmLEZCX3Njb3JlMSxieV9ncm91cCA9IEYpCmRhdGEgPC0gY2JpbmQoZGYsaW5kZXggPSAxOm5yb3coZGYpLGNsdXN0ZXIgPSBJZGVudHMoZHMyX0FDKSkKCihnZ3Bsb3QoZGF0YSxhZXMoeD1TTUNfc2NvcmUxKSkgKyBnZW9tX3BvaW50KGFlcyh5ID0gQkdOLCBjb2xvciA9IGNsdXN0ZXIpLGFscGhhID0gMSkgKyBnZW9tX3Ntb290aChhZXMoeSA9IEJHTiksIGNvbG9yID0gInJlZCIpICsgdGhlbWVfY2xhc3NpYygpICsgcmlkZ2V0aGVtZSArIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDEsNSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9yc19saXN0KSArIHRoZW1lKGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMSwiY20iKSkgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZT0xMCkpKSkgCgooZ2dwbG90KGRhdGEsYWVzKHg9RkJfc2NvcmUxKSkgKyBnZW9tX3BvaW50KGFlcyh5ID0gTFVNLCBjb2xvciA9IGNsdXN0ZXIpLGFscGhhID0gMSkgKyBnZW9tX3Ntb290aChhZXMoeSA9IEJHTiksIGNvbG9yID0gImdyZWVuIikgKyB0aGVtZV9jbGFzc2ljKCkgKyByaWRnZXRoZW1lICtzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygxLDUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xvcnNfbGlzdCkgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZT0xMCkpKSkKCgpkZiA8LSBGZXRjaERhdGEoZHMyX1BBLHZhcnMgPSBjKCJGQl9zY29yZTEiLCJTTUNfc2NvcmUxIiwiQkdOIiwiTFVNIiwiVU1BUF8xIiwiVU1BUF8yIikpCiMgZGYgPC0gYXJyYW5nZShkZixGQl9zY29yZTEsYnlfZ3JvdXAgPSBGKQpkYXRhIDwtIGNiaW5kKGRmLGluZGV4ID0gMTpucm93KGRmKSxjbHVzdGVyID0gSWRlbnRzKGRzMl9QQSkpCgpnZ3Bsb3QoZGF0YSxhZXMoeD1TTUNfc2NvcmUxKSkgKyBnZW9tX3BvaW50KGFlcyh5ID0gQkdOLCBjb2xvciA9IGNsdXN0ZXIpLGFscGhhID0gMSkgKyBnZW9tX3Ntb290aChhZXMoeSA9IEJHTiksIGNvbG9yID0gInJlZCIpICsgdGhlbWVfY2xhc3NpYygpICsgcmlkZ2V0aGVtZSArIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDEsNSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9yc19saXN0KSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplPTEwKSkpCgpnZ3Bsb3QoZGF0YSxhZXMoeD1GQl9zY29yZTEpKSArIGdlb21fcG9pbnQoYWVzKHkgPSBMVU0sIGNvbG9yID0gY2x1c3RlciksYWxwaGEgPSAxKSArIGdlb21fc21vb3RoKGFlcyh5ID0gQkdOKSwgY29sb3IgPSAiZ3JlZW4iKSArIHRoZW1lX2NsYXNzaWMoKSArIHJpZGdldGhlbWUgK3NjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDEsNSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9yc19saXN0KSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplPTEwKSkpCgojIGdncGxvdChkYXRhLGFlcyh4PUZCX3Njb3JlMSkpICsgZ2VvbV9wb2ludChhZXMoeSA9IEJHTiksY29sb3IgPSAiI2UyYjM5OCIsYWxwaGEgPSAxKSArIGdlb21fc21vb3RoKGFlcyh5ID0gQkdOKSwgY29sb3IgPSAicmVkIikgKyBnZW9tX3BvaW50KGFlcyh5PUxVTSksY29sb3IgPSAiI2QxZWJhOCIsYWxwaGEgPSAxKSArIGdlb21fc21vb3RoKGFlcyh5ID0gTFVNKSwgY29sb3IgPSAiZ3JlZW4iKSArIHRoZW1lX2NsYXNzaWMoKSArIHJpZGdldGhlbWUgK3NjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDEsNSkpCgpgYGAKCi0tLQoKIyBmaWcuRAojIyBBQy0+UEEKYGBge3J9CnNvdXJjZSgiWEdCb29zdF93cmFwcGVyLlIiKQpzb3VyY2UoInRpYW5mZW5nUndyYXBwZXJzLlIiKQoKSWRlbnRzKGRzMl9BQykgPC0gZmFjdG9yKElkZW50cyhkczJfQUMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIkZpYnJvYmxhc3QiLCJGaWJyb215b2N5dGUiLCJQZXJpY3l0ZSIsIlNNQzEiLCJTTUMyIiwiVW5hc3NpZ25lZCIpKQoKYnN0X21vZGVsIDwtIFhHQm9vc3RfdHJhaW5fZnJvbV9zZXVvYmooZHMyX0FDKQpkczJfUEEgPC0gWEdCb29zdF9wcmVkaWN0X2Zyb21fc2V1b2JqKGRzMl9QQSxic3RfbW9kZWwpCgpjb25mdXNlX21hdCA8LSBYR0Jvb3N0X3ByZWRpY3RfZnJvbV9zZXVvYmooZHMyX1BBLCBic3RfbW9kZWwsIHJldHVybl9jb25mdXNlX21hdHJpeCA9IFQpCiMgc2Fua2V5X3Bsb3QoY29uZnVzZV9tYXQsc2Vzc2lvbiA9ICJBQyAtPiBQQSIpCmRzMl9QQSA8LSBwcm9qZWN0MnJlZl9jZWxsdHlwZTIoZHMyX1BBLCBkczJfQUMpCgpkczJfUEEkcmVmX2NlbGx0eXBlIDwtIGZhY3RvcihkczJfUEEkcmVmX2NlbGx0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJGaWJyb2JsYXN0IiwiRmlicm9teW9jeXRlIiwiUGVyaWN5dGUiLCJTTUMxIiwiU01DMiIsIlVuYXNzaWduZWQiKSkKCnVtYXBwbG90KGRzMl9QQSxncm91cC5ieSA9ICJyZWZfY2VsbHR5cGUiLCByZXBlbCA9IFQsIGxhYmVsLnNpemUgPSA1KSAlPiUgCiAgZ2dzYXZlKCIuL2ZpZzIvc3VwX2RzMlBBX3VtYXAyLnBuZyIscGxvdCA9IC4sIGRldmljZSA9IHBuZywgaGVpZ2h0ID0gNCwgd2lkdGggPSA2KQoKY29uZnVzZV9tYXQgPC0gWEdCb29zdF9wcmVkaWN0X2Zyb21fc2V1b2JqKGRzMl9QQSwgYnN0X21vZGVsLCByZXR1cm5fY29uZnVzZV9tYXRyaXggPSBUKQoKbGFiZWwxID0gZGltbmFtZXMoY29uZnVzZV9tYXQpJHByZQpsYWJlbDIgPSBkaW1uYW1lcyhjb25mdXNlX21hdCkkdHJ1ZQoKc291cmNlcyA8LSByZXAoMDoobGVuZ3RoKGxhYmVsMSkgLSAxKSwgZWFjaCA9IGxlbmd0aChsYWJlbDIpKSAjIOazqOaEj+i/memHjOeahGVhY2jlkox0aW1lc+eahOWMuuWIqwpjb2xvcnMgPC0gcmVwKGFlcm9fY29sb3JzX2xpc3RbYygxLDIsMyw1LDYpXSwgZWFjaCA9IGxlbmd0aChsYWJlbDIpKQp0YXJnZXRzIDwtIHJlcChsZW5ndGgobGFiZWwxKSArIDA6KGxlbmd0aChsYWJlbDIpIC0gMSksIHRpbWVzID0gbGVuZ3RoKGxhYmVsMSkpCgpwbG90X2x5KAogICAgdHlwZSA9ICJzYW5rZXkiLCBvcmllbnRhdGlvbiA9ICJoIiwKICAgIG5vZGUgPSBsaXN0KAogICAgICAgIGxhYmVsID0gTlVMTCwKICAgICAgICBjb2xvciA9IGMoY29sb3JzX2xpc3RbYygxLDIsMyw1LDYpXSwgY29sb3JzX2xpc3RbYygyOjUpXSksIHBhZCA9IDE1LCB0aGlja25lc3MgPSAzMCwKICAgICAgICBsaW5lID0gbGlzdChjb2xvciA9ICJibGFjayIsIHdpZHRoID0gMSkKICAgICksCiAgICBsaW5rID0gbGlzdCgKICAgICAgICBzb3VyY2UgPSBzb3VyY2VzLCB0YXJnZXQgPSB0YXJnZXRzLAogICAgICAgIHZhbHVlID0gYXMubnVtZXJpYyhjb25mdXNlX21hdCksCiAgICAgICAgY29sb3IgPSBjb2xvcnMKICAgICkKKSAlPiUgbGF5b3V0KHRpdGxlID0gIkFDIC0+IFBBIiwgZm9udCA9IGxpc3QoZmFtaWx5ID0gIkFyaWFsIiwgc2l6ZSA9IDIwLCBjb2xvciA9ICJibGFjayIpKQoKYGBgCiMjIyBudW1lcmljYWwgdW1hcApgYGB7cn0KZW1iZWRkaW5nIDwtIEZldGNoRGF0YShvYmplY3QgPSBkczJfUEEsIHZhcnMgPSBjKCJVTUFQXzEiLCAiVU1BUF8yIikpCmVtYmVkZGluZyA8LSBjYmluZChlbWJlZGRpbmcsIGNiaW5kKGRzMl9QQSRYMCxkczJfUEEkWDEsZHMyX1BBJFgyLGRzMl9QQSRYMykpCgpnZ29iaiA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9wb2ludChkYXRhID0gZW1iZWRkaW5nW2VtYmVkZGluZyRgMWA+MC4xLF0sIAogICAgICAgICAgICAgYWVzKHggPSBVTUFQXzEsIHkgPSBVTUFQXzIsIGNvbG9yID0gYDFgKSwgc2hhcGU9MTYsIHNpemUgPSAzLCBhbHBoYT0wLjUpICsgCiAgc2NhbGVfY29sb3JfZ3JhZGllbnQoJzAnLCBsb3cgPSAiI0ZGRkZGRjAwIiwgaGlnaCA9ICIjNmRjMGE2IikgKwogIG5ld19zY2FsZSgiY29sb3IiKSArCiAgICBnZW9tX3BvaW50KGRhdGEgPSBlbWJlZGRpbmdbZW1iZWRkaW5nJGAyYD4wLjEsXSwgCiAgICAgICAgICAgICBhZXMoeCA9IFVNQVBfMSwgeSA9IFVNQVBfMiwgY29sb3IgPSBgMmApLHNoYXBlPTE2LCBzaXplID0gMywgYWxwaGE9MC41KSArIAogIHNjYWxlX2NvbG9yX2dyYWRpZW50KCcxJywgbG93ID0gIiNGRkZGRkYwMCIsIGhpZ2ggPSAiI2UyYjM5OCIpICsKICAgbmV3X3NjYWxlKCJjb2xvciIpICsKICAgIGdlb21fcG9pbnQoZGF0YSA9IGVtYmVkZGluZ1tlbWJlZGRpbmckYDNgPjAuMSxdLCAKICAgICAgICAgICAgIGFlcyh4ID0gVU1BUF8xLCB5ID0gVU1BUF8yLCBjb2xvciA9IGAzYCksc2hhcGU9MTYsIHNpemUgPSAzLCBhbHBoYT0wLjUpICsgCiAgc2NhbGVfY29sb3JfZ3JhZGllbnQoJzInLCBsb3cgPSAiI0ZGRkZGRjAwIiwgaGlnaCA9ICIjZTJhMmNhIikgKwogIG5ld19zY2FsZSgiY29sb3IiKSArCiAgICBnZW9tX3BvaW50KGRhdGEgPSBlbWJlZGRpbmdbZW1iZWRkaW5nJGA0YD4wLjEsXSwgCiAgICAgICAgICAgICBhZXMoeCA9IFVNQVBfMSwgeSA9IFVNQVBfMiwgY29sb3IgPSBgNGApLHNoYXBlPTE2LCBzaXplID0gMywgYWxwaGE9MC41KSArIAogIHNjYWxlX2NvbG9yX2dyYWRpZW50KCczJywgbG93ID0gIiNGRkZGRkYwMCIsIGhpZ2ggPSAiI2QxZWJhOCIpICsKICAgICAgICB4bGFiKCJVTUFQIDEiKSArIHlsYWIoIlVNQVAgMiIpICArCiAgICAgICAgdGhlbWUoYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgwLjIsICJjbSIpKSkpICsKICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gTlVMTCkgKwogICAgICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBOVUxMKSArIAogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQpnZ3NhdmUoIi4vZmlnMi9zdXBfZHMyUEFfdW1hcC5wbmciLGRldmljZSA9IHBuZywgcGxvdCA9IGdnb2JqLCBoZWlnaHQgPSAxMCx3aWR0aCA9IDEwKQpgYGAKCgojIyBQQS0+QUMKIyMjIHRyYWluIG9uIFBBCmBgYHtyfQpJZGVudHMoZHMyX1BBKSA8LSBmYWN0b3IoSWRlbnRzKGRzMl9QQSksIAogICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiRmlicm9ibGFzdCIsIkZpYnJvbXlvY3l0ZSIsIlBlcmljeXRlIiwiU01DMSIsIlNNQzIiLCJVbmFzc2lnbmVkIikpCgpic3RfbW9kZWwgPC0gWEdCb29zdF90cmFpbl9mcm9tX3NldW9iaihkczJfUEEpCmRzMl9BQyA8LSBYR0Jvb3N0X3ByZWRpY3RfZnJvbV9zZXVvYmooZHMyX0FDLGJzdF9tb2RlbCkKdW1hcHBsb3QoZHMyX0FDLGdyb3VwLmJ5ID0gInByb2plY3RlZF9pZGVudHMiKQpkczJfQUMgPC0gcHJvamVjdDJyZWZfY2VsbHR5cGUyKGRzMl9BQyxkczJfUEEpCgpkczJfQUMkcmVmX2NlbGx0eXBlIDwtIGZhY3RvcihkczJfQUMkcmVmX2NlbGx0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJGaWJyb2JsYXN0IiwiRmlicm9teW9jeXRlIiwiUGVyaWN5dGUiLCJTTUMxIiwiU01DMiIsIlVuYXNzaWduZWQiKSkKCnVtYXBwbG90KGRzMl9BQyxncm91cC5ieSA9ICJyZWZfY2VsbHR5cGUiLCByZXBlbCA9IFQsIGxhYmVsLnNpemUgPSA1KSAgJT4lIAogIGdnc2F2ZSgiLi9maWcyL3N1cF9kczJBQ191bWFwMi5wbmciLHBsb3QgPSAuLCBkZXZpY2UgPSBwbmcsIGhlaWdodCA9IDQsIHdpZHRoID0gNikKCmNvbmZ1c2VfbWF0IDwtIFhHQm9vc3RfcHJlZGljdF9mcm9tX3NldW9iaihkczJfQUMsIGJzdF9tb2RlbCwgcmV0dXJuX2NvbmZ1c2VfbWF0cml4ID0gVCkKIyBzYW5rZXlfcGxvdChjb25mdXNlX21hdCxzZXNzaW9uID0gIlBBIC0+IEFDIikKCmxhYmVsMSA9IGRpbW5hbWVzKGNvbmZ1c2VfbWF0KSRwcmUKbGFiZWwyID0gZGltbmFtZXMoY29uZnVzZV9tYXQpJHRydWUKY29uZnVzZV9tYXQKc291cmNlcyA8LSByZXAoMDoobGVuZ3RoKGxhYmVsMSkgLSAxKSwgZWFjaCA9IGxlbmd0aChsYWJlbDIpKSAjIOazqOaEj+i/memHjOeahGVhY2jlkox0aW1lc+eahOWMuuWIqwpjb2xvcnMgPC0gcmVwKGFlcm9fY29sb3JzX2xpc3RbMjo2XSwgZWFjaCA9IGxlbmd0aChsYWJlbDIpKQp0YXJnZXRzIDwtIHJlcChsZW5ndGgobGFiZWwxKSArIDA6KGxlbmd0aChsYWJlbDIpIC0gMSksIHRpbWVzID0gbGVuZ3RoKGxhYmVsMSkpCgpwbG90X2x5KAogICAgdHlwZSA9ICJzYW5rZXkiLCBvcmllbnRhdGlvbiA9ICJoIiwKICAgIG5vZGUgPSBsaXN0KAogICAgICAgIGxhYmVsID0gTlVMTCwKICAgICAgICBjb2xvciA9IGMoY29sb3JzX2xpc3RbMjo2XSwgY29sb3JzX2xpc3RbYygxOjMsNSldKSwgcGFkID0gMTUsIHRoaWNrbmVzcyA9IDMwLAogICAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gImJsYWNrIiwgd2lkdGggPSAxKQogICAgKSwKICAgIGxpbmsgPSBsaXN0KAogICAgICAgIHNvdXJjZSA9IHNvdXJjZXMsIHRhcmdldCA9IHRhcmdldHMsCiAgICAgICAgdmFsdWUgPSBhcy5udW1lcmljKGNvbmZ1c2VfbWF0KSwKICAgICAgICBjb2xvciA9IGNvbG9ycwogICAgKQopICU+JSBsYXlvdXQodGl0bGUgPSAiUEEgLT4gQUMiLCBmb250ID0gbGlzdChmYW1pbHkgPSAiQXJpYWwiLCBzaXplID0gMjAsIGNvbG9yID0gImJsYWNrIikpCmBgYAojIyMgbnVtZXJpY2FsIHVtYXAKYGBge3J9CmVtYmVkZGluZyA8LSBGZXRjaERhdGEob2JqZWN0ID0gZHMyX0FDLCB2YXJzID0gYygiVU1BUF8xIiwgIlVNQVBfMiIpKQplbWJlZGRpbmcgPC0gY2JpbmQoZW1iZWRkaW5nLCBjYmluZChkczJfQUMkWDAsZHMyX0FDJFgxLGRzMl9BQyRYMixkczJfQUMkWDMpKQoKZ2dvYmogPC0gZ2dwbG90KCkgKwogIGdlb21fcG9pbnQoZGF0YSA9IGVtYmVkZGluZ1tlbWJlZGRpbmckYDFgPjAuMSxdLCAKICAgICAgICAgICAgIGFlcyh4ID0gVU1BUF8xLCB5ID0gVU1BUF8yLCBjb2xvciA9IGAxYCksIHNoYXBlPTE2LCBzaXplID0gMywgYWxwaGE9MC41KSArIAogIHNjYWxlX2NvbG9yX2dyYWRpZW50KCcwJywgbG93ID0gIiNGRkZGRkYwMCIsIGhpZ2ggPSAiIzZkYzBhNiIpICsKICBuZXdfc2NhbGUoImNvbG9yIikgKwogICAgZ2VvbV9wb2ludChkYXRhID0gZW1iZWRkaW5nW2VtYmVkZGluZyRgMmA+MC4xLF0sIAogICAgICAgICAgICAgYWVzKHggPSBVTUFQXzEsIHkgPSBVTUFQXzIsIGNvbG9yID0gYDJgKSxzaGFwZT0xNiwgc2l6ZSA9IDMsIGFscGhhPTAuNSkgKyAKICBzY2FsZV9jb2xvcl9ncmFkaWVudCgnMScsIGxvdyA9ICIjRkZGRkZGMDAiLCBoaWdoID0gIiNlMmIzOTgiKSArCiAgIG5ld19zY2FsZSgiY29sb3IiKSArCiAgICBnZW9tX3BvaW50KGRhdGEgPSBlbWJlZGRpbmdbZW1iZWRkaW5nJGAzYD4wLjEsXSwgCiAgICAgICAgICAgICBhZXMoeCA9IFVNQVBfMSwgeSA9IFVNQVBfMiwgY29sb3IgPSBgM2ApLHNoYXBlPTE2LCBzaXplID0gMywgYWxwaGE9MC41KSArIAogIHNjYWxlX2NvbG9yX2dyYWRpZW50KCcyJywgbG93ID0gIiNGRkZGRkYwMCIsIGhpZ2ggPSAiI2UyYTJjYSIpICsKICBuZXdfc2NhbGUoImNvbG9yIikgKwogICAgZ2VvbV9wb2ludChkYXRhID0gZW1iZWRkaW5nW2VtYmVkZGluZyRgNGA+MC4xLF0sIAogICAgICAgICAgICAgYWVzKHggPSBVTUFQXzEsIHkgPSBVTUFQXzIsIGNvbG9yID0gYDRgKSxzaGFwZT0xNiwgc2l6ZSA9IDMsIGFscGhhPTAuNSkgKyAKICBzY2FsZV9jb2xvcl9ncmFkaWVudCgnMycsIGxvdyA9ICIjRkZGRkZGMDAiLCBoaWdoID0gIiNkMWViYTgiKSArCiAgICAgICAgeGxhYigiVU1BUCAxIikgKyB5bGFiKCJVTUFQIDIiKSAgKwogICAgICAgIHRoZW1lKGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShhcnJvdyA9IGFycm93KGxlbmd0aCA9IHVuaXQoMC4yLCAiY20iKSkpKSArCiAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IE5VTEwpICsKICAgICAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gTlVMTCkgKyAKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKZ2dzYXZlKCIuL2ZpZzIvc3VwX2RzMkFDX3VtYXAucG5nIixkZXZpY2UgPSBwbmcsIHBsb3QgPSBnZ29iaixoZWlnaHQgPSAxMCx3aWR0aCA9IDEwKQpgYGAKCgojIEdTVkEKYGBge3J9CkdTVkFyZXMgPC0gcmVhZFJEUygiR1NWQXJlcy5yZHMiKQplcyA8LSBkYXRhLmZyYW1lKHQoR1NWQXJlcyksc3RyaW5nc0FzRmFjdG9ycz1GKSAgI+WPr+inhuWMluebuOWFs+mAmui3r+eahOWcqHVtYXDkuIrogZrpm4bmg4XlhrUKZHMyX0FDIDwtIEFkZE1ldGFEYXRhKGRzMl9BQywgZXMpCmYoIkNVSV9UQ0YyMV9UQVJHRVRTX1VQIiwgbGFiZWwgPSBGLCBkczJfQUMpICtzY2FsZV9jb2xvdXJfZ3JhZGllbnQobG93PSIjMUU5MEZGIiwgaGlnaD0iI2ZmMjEyMSIpCgpkczJfUEEgPC0gQWRkTWV0YURhdGEoZHMyX1BBLCBlcykKZigiQ1VJX1RDRjIxX1RBUkdFVFNfVVAiLCBsYWJlbCA9IEYsIGRzMl9QQSkgK3NjYWxlX2NvbG91cl9ncmFkaWVudChsb3c9IiMxRTkwRkYiLCBoaWdoPSIjZmYyMTIxIikKYGBgCgpBZGQgYSBuZXcgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpJbnNlcnQgQ2h1bmsqIGJ1dHRvbiBvbiB0aGUgdG9vbGJhciBvciBieSBwcmVzc2luZyAqQ3RybCtBbHQrSSouCgpXaGVuIHlvdSBzYXZlIHRoZSBub3RlYm9vaywgYW4gSFRNTCBmaWxlIGNvbnRhaW5pbmcgdGhlIGNvZGUgYW5kIG91dHB1dCB3aWxsIGJlIHNhdmVkIGFsb25nc2lkZSBpdCAoY2xpY2sgdGhlICpQcmV2aWV3KiBidXR0b24gb3IgcHJlc3MgKkN0cmwrU2hpZnQrSyogdG8gcHJldmlldyB0aGUgSFRNTCBmaWxlKS4KClRoZSBwcmV2aWV3IHNob3dzIHlvdSBhIHJlbmRlcmVkIEhUTUwgY29weSBvZiB0aGUgY29udGVudHMgb2YgdGhlIGVkaXRvci4gQ29uc2VxdWVudGx5LCB1bmxpa2UgKktuaXQqLCAqUHJldmlldyogZG9lcyBub3QgcnVuIGFueSBSIGNvZGUgY2h1bmtzLiBJbnN0ZWFkLCB0aGUgb3V0cHV0IG9mIHRoZSBjaHVuayB3aGVuIGl0IHdhcyBsYXN0IHJ1biBpbiB0aGUgZWRpdG9yIGlzIGRpc3BsYXllZC4K